﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Security;
using System.Security.Principal;
using System.Diagnostics;
using SPMS.Log.Utility;

namespace SPMS.Log.Core
{
    /// <summary>
    /// 日志条目
    /// </summary>
    /// <remarks>用于描述用于输出的日志条目信息</remarks>
    /// <history>
    /// [zanezeng]               2009/9/22 17:20    创建
    /// </history>
    [Serializable]
    public sealed class LogEntry : INamedPropertyProvider
    {
        #region ---Constructor

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="stackBoundaryType">调用堆栈的分界类型</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( Type stackBoundaryType,
                         string loggerName,
                         Level level,
                         object message,
                         Exception exception )
            : this( stackBoundaryType, loggerName, level, message, exception, null )
        {
        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="stackBoundaryType">调用堆栈的分界类型</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <param name="properties">附加属性</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( Type stackBoundaryType,
                         string loggerName,
                         Level level,
                         object message,
                         Exception exception,
                         IDictionary<string, object> properties )
        {
            //保存参数
            this.m_StackBoundaryType = stackBoundaryType;
            this.m_LoggerName = (null == loggerName) ? DEFAULT_UNKNOWNNAME : loggerName;
            this.m_Level = level;
            this.m_Message = message;
            this.m_Exception = exception;

            //追加扩展属性
            this.AppendExtendedProperties( properties, true );

            //初始化
            this.Intialize();
        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="fileName">日志事件发生点所在文件的名称</param>
        /// <param name="lineNumber">日志事件发生点所在的文件行号</param>
        /// <param name="columnNumber">日志事件发生点所在的文件列号</param>
        /// <param name="typeName">日志事件发生点所在的类型名称</param>
        /// <param name="methodName">日志事件发生点所在的方法名称</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <param name="properties">附加属性</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( string fileName,
                         int lineNumber,
                         int columnNumber,
                         string typeName,
                         string methodName,
                         string loggerName,
                         Level level,
                         object message,
                         Exception exception,
                         IDictionary<string, object> properties )
        {
            //保存参数
            this.m_FileName = (null == fileName) ? DEFAULT_UNKNOWNNAME : fileName;
            this.m_LineNumber = lineNumber;
            this.m_ColumnNumber = columnNumber;
            this.m_TypeName = (null == typeName) ? DEFAULT_UNKNOWNNAME : typeName;
            this.m_MethodName = (null == methodName) ? DEFAULT_UNKNOWNNAME : methodName;
            this.m_LoggerName = (null == loggerName) ? DEFAULT_UNKNOWNNAME : loggerName;
            this.m_Level = level;
            this.m_Message = message;
            this.m_Exception = exception;

            //追加扩展属性
            this.AppendExtendedProperties( properties, true );

            //初始化
            this.Intialize();
        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="fileName">日志事件发生点所在文件的名称</param>
        /// <param name="lineNumber">日志事件发生点所在的文件行号</param>
        /// <param name="columnNumber">日志事件发生点所在的文件列号</param>
        /// <param name="typeName">日志事件发生点所在的类型名称</param>
        /// <param name="methodName">日志事件发生点所在的方法名称</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="threadName">日志事件发生线程的名称</param>
        /// <param name="identity">当前系统用户的标识名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <param name="properties">附加属性</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( string fileName,
                         int lineNumber,
                         int columnNumber,
                         string typeName,
                         string methodName,
                         string loggerName,
                         string threadName,
                         string identity,
                         Level level,
                         object message,
                         Exception exception,
                         IDictionary<string, object> properties )
        {
            //保存参数
            this.m_FileName = (null == fileName) ? DEFAULT_UNKNOWNNAME : fileName;
            this.m_LineNumber = lineNumber;
            this.m_ColumnNumber = columnNumber;
            this.m_TypeName = (null == typeName) ? DEFAULT_UNKNOWNNAME : typeName;
            this.m_MethodName = (null == methodName) ? DEFAULT_UNKNOWNNAME : methodName;
            this.m_LoggerName = (null == loggerName) ? DEFAULT_UNKNOWNNAME : loggerName;
            this.m_ThreadName = threadName;
            this.m_Identity = identity;
            this.m_Level = level;
            this.m_Message = message;
            this.m_Exception = exception;

            //追加扩展属性
            this.AppendExtendedProperties( properties, true );

            //初始化
            this.Intialize();
        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="location">当前的执行点信息</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( ExecutingLocation location,
                         string loggerName,
                         Level level,
                         object message,
                         Exception exception )
            : this( location, loggerName, level, message, exception, null )
        {

        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>的新实例
        /// </summary>
        /// <param name="location">当前的执行点信息</param>
        /// <param name="loggerName">日志记录器的名称</param>
        /// <param name="level">日志的级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常</param>
        /// <param name="properties">附加属性</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:39    创建
        /// </history>
        public LogEntry( ExecutingLocation location,
                         string loggerName,
                         Level level,
                         object message,
                         Exception exception,
                         IDictionary<string, object> properties )
        {
            //判断执行点是否为NULL
            if (null != location)
            {
                //保存参数
                this.m_FileName = (null == location.FileName) ? DEFAULT_UNKNOWNNAME : location.FileName;
                this.m_LineNumber = location.LineNumber;
                this.m_ColumnNumber = location.ColumnNumber;
                this.m_TypeName = (null == location.ExecutingType) ? DEFAULT_UNKNOWNNAME : location.ExecutingType.FullName;
                this.m_MethodName = (null == location.ExecutingMethod) ? DEFAULT_UNKNOWNNAME : location.ExecutingMethod.Name;
                this.m_ThreadName = (null == location.ThreadName) ? DEFAULT_UNKNOWNNAME : location.ThreadName;
                this.m_DomainName = (null == location.DomainName) ? DEFAULT_UNKNOWNNAME : location.DomainName;
                this.m_UserName = (null == location.CurrentWindowsUsername) ? DEFAULT_UNKNOWNNAME : location.CurrentWindowsUsername;
                this.m_Identity = (null == location.CurrentSystemUsername) ? DEFAULT_UNKNOWNNAME : location.CurrentSystemUsername;
            }

            //保存参数
            this.m_LoggerName = (null == loggerName) ? DEFAULT_UNKNOWNNAME : loggerName;
            this.m_Level = level;
            this.m_Message = message;
            this.m_Exception = exception;

            //追加扩展属性
            this.AppendExtendedProperties( properties, true );

            //初始化
            this.Intialize();
        }

        /// <summary>
        /// 初始化类型<see cref="LogEntry"/>
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/11/25 13:32    创建
        /// </history>
        static LogEntry()
        {
            //初始化进程编号
            s_ProcessID = GetCurrentProcessID();
        }

        #endregion

        #region ---INamedPropertyProvider

        /// <summary>
        /// 获得给定名称的属性值
        /// </summary>
        /// <value>给定名称的属性值，如果给定名称的属性值不存在，则返回<c>Null</c></value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 9:47    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 9:53    创建
        /// </history>
        public object this[string name]
        {
            get
            {
                //判断名称是否为Null或者为空字符串
                if (string.IsNullOrEmpty( name ))
                {
                    //如果名称为Null或者为空字符串，则返回Null
                    return null;
                }

                //获得字符串比较器
                StringComparer comparer = StringComparer.InvariantCultureIgnoreCase;

                //判断是否为时间戳
                if (0 == comparer.Compare( name, "Timestamp" ))
                {
                    return this.Timestamp;
                }
                //判断是否为日志事件的级别
                else if (0 == comparer.Compare( name, "Level" ))
                {
                    return this.Level;
                }
                //判断是否为日志事件的描述信息
                else if (0 == comparer.Compare( name, "Message" ))
                {
                    return this.Message;
                }
                //判断是否为记录当前日志消息的日志记录器的名称
                else if (0 == comparer.Compare( name, "LoggerName" ))
                {
                    return this.LoggerName;
                }
                //判断是否为日志事件中包含的异常
                else if (0 == comparer.Compare( name, "Exception" ))
                {
                    return this.Exception;
                }
                //判断是否为当前已登录到Windows操作系统的人员的用户名
                else if (0 == comparer.Compare( name, "UserName" ))
                {
                    return this.UserName;
                }
                //判断是否为当前系统用户的标识名称
                else if (0 == comparer.Compare( name, "Identity" ))
                {
                    return this.Identity;
                }
                //判断是否为日志事件发生的进程的进程编号
                else if (0 == comparer.Compare( name, "ProcessID" ))
                {
                    return this.ProcessID;
                }
                //判断是否为日志事件发生线程的名称
                else if (0 == comparer.Compare( name, "ThreadName" ))
                {
                    return this.ThreadName;
                }
                //判断是否为应用程序域的名称
                else if (0 == comparer.Compare( name, "DomainName" ))
                {
                    return this.DomainName;
                }
                //判断是否为日志事件发生点所在类型的名称
                else if (0 == comparer.Compare( name, "TypeName" ))
                {
                    return this.TypeName;
                }
                //判断是否为日志事件发生点所在方法的名称
                else if (0 == comparer.Compare( name, "MethodName" ))
                {
                    return this.MethodName;
                }
                //判断是否为日志事件发生点所在文件的名称
                else if (0 == comparer.Compare( name, "FileName" ))
                {
                    return this.FileName;
                }
                //判断是否为日志事件发生点所在文件的行号
                else if (0 == comparer.Compare( name, "LineNumber" ))
                {
                    return this.LineNumber;
                }
                //判断是否为日志事件发生点所在文件的列号
                else if (0 == comparer.Compare( name, "ColumnNumber" ))
                {
                    return this.ColumnNumber;
                }
                //判断是否有扩展属性
                else if (this.HasExtendedProperty)
                {
                    //用于保存属性值
                    object propertyValue;

                    //尝试从扩展属性中获得
                    if (this.ExtendedProperties.TryGetValue( name, out propertyValue ))
                    {
                        //返回属性值
                        return propertyValue;
                    }

                }

                //默认返回NULL
                return null;
            }
        }

        #endregion

        #region ---Property

        /// <summary>
        /// 获得日志事件发生的时间点
        /// </summary>
        /// <value>日志事件发生的时间点</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:27    创建
        /// </history>
        public DateTime Timestamp
        {
            get
            {
                return this.m_TimeStamp;
            }

        }

        /// <summary>
        /// 获得日志事件的级别
        /// </summary>
        /// <value>日志事件的级别</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 16:07    创建
        /// </history>
        public Level Level
        {
            get
            {
                return this.m_Level;
            }
        }

        /// <summary>
        /// 获得日志事件的描述信息
        /// </summary>
        /// <value>日志事件的描述信息</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 16:11    创建
        /// </history>
        public object Message
        {
            get
            {
                return this.m_Message;
            }
        }

        /// <summary>
        /// 获得记录当前日志消息的日志记录器的名称
        /// </summary>
        /// <value>记录当前日志消息的日志记录器的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 16:12    创建
        /// </history>
        public string LoggerName
        {
            get
            {
                return this.m_LoggerName;
            }
        }

        /// <summary>
        /// 获得日志事件中包含的异常
        /// </summary>
        /// <value>日志事件中包含的异常</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 16:13    创建
        /// </history>
        public Exception Exception
        {
            get
            {
                return this.m_Exception;
            }
        }

        /// <summary>
        /// 获得获取当前已登录到Windows操作系统的人员的用户名
        /// </summary>
        /// <value>当前已登录到Windows操作系统的人员的用户名</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:10    创建
        /// </history>
        public string UserName
        {
            get
            {
                //返回登录用户名称
                return this.m_UserName;
            }
        }

        /// <summary>
        /// 获得当前系统用户的标识名称
        /// </summary>
        /// <value>当前系统用户的标识名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:14    创建
        /// </history>
        public string Identity
        {
            get
            {
                //返回登录用户名称
                return this.m_Identity;
            }
        }

        /// <summary>
        /// 获得当前进程的进程编号
        /// </summary>
        /// <value>当前进程的进程编号</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/11/25 13:30    创建
        /// </history>
        public int ProcessID
        {
            get
            {
                return s_ProcessID;
            }
        }

        /// <summary>
        /// 获得日志事件发生线程的名称
        /// </summary>
        /// <value>日志事件发生线程的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:28    创建
        /// </history>
        public string ThreadName
        {
            get
            {
                //返回线程名称
                return this.m_ThreadName;
            }
        }

        /// <summary>
        /// 获得应用程序域的名称
        /// </summary>
        /// <value>应用程序域的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:15    创建
        /// </history>
        public string DomainName
        {
            get
            {
                //返回应用程序域的名称
                return this.m_DomainName;
            }
        }

        /// <summary>
        /// 获得日志事件发生点所在类型的名称
        /// </summary>
        /// <value>日志事件发生点所在类型的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:22    创建
        /// </history>
        public string TypeName
        {
            get
            {
                //返回类型信息
                return this.m_TypeName;
            }
        }

        /// <summary>
        /// 获得日志事件发生点所在方法的名称
        /// </summary>
        /// <value>日志事件发生点所在方法的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:22    创建
        /// </history>
        public string MethodName
        {
            get
            {
                //返回方法名称
                return this.m_MethodName;
            }
        }

        /// <summary>
        /// 获得日志事件发生点所在文件的名称
        /// </summary>
        /// <value>日志事件发生点所在文件的名称</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:24    创建
        /// </history>
        public string FileName
        {
            get
            {
                //返回文件名称
                return this.m_FileName;
            }
        }

        /// <summary>
        /// 获得日志事件发生点所在文件的行号
        /// </summary>
        /// <value>日志事件发生点所在文件的行号</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:24    创建
        /// </history>
        public int LineNumber
        {
            get
            {
                //返回行号
                return this.m_LineNumber;
            }
        }

        /// <summary>
        /// 获得日志事件发生点所在文件的列号
        /// </summary>
        /// <value>日志事件发生点所在文件的列号</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:24    创建
        /// </history>
        public int ColumnNumber
        {
            get
            {
                //返回列号
                return this.m_ColumnNumber;
            }
        }

        /// <summary>
        /// 获得扩展属性
        /// </summary>
        /// <value>扩展属性</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 9:33    创建
        /// </history>
        public IDictionary<string, object> ExtendedProperties
        {
            get
            {
                //判断扩展属性是否创建
                if (null == this.m_ExtendedProperties)
                {
                    //创建扩展属性
                    this.m_ExtendedProperties = new Dictionary<string, object>();
                }

                //返回扩展属性
                return this.m_ExtendedProperties;
            }
        }

        /// <summary>
        /// 获得一个值，该值用于判断是否有扩展属性
        /// </summary>
        /// <value>
        /// 	<c>true</c>：有扩展属性<br/>
        /// 	<c>false</c>：没有扩展属性
        /// </value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 17:46    创建
        /// </history>
        public bool HasExtendedProperty
        {
            get
            {
                return null != this.m_ExtendedProperties;
            }
        }

        #endregion

        #region ---Public Method

        /// <summary>
        /// 追加扩展属性
        /// </summary>
        /// <param name="properties">要追加的扩展属性</param>
        /// <param name="isOverWrite">是否覆盖现有的同名属性</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/21 11:59    创建
        /// </history>
        public void AppendExtendedProperties( ICollection<KeyValuePair<string, object>> properties, bool isOverWrite )
        {
            //判定是否有扩展属性
            if (null == properties || 0 == properties.Count)
            {
                //如果没有扩展属性，则直接返回
                return;
            }

            //判断是否有扩展属性
            if (null != properties && properties.Count > 0)
            {
                //循环添加扩展属性
                foreach (KeyValuePair<string, object> item in properties)
                {
                    //判断是否覆盖和是否有同名属性
                    if (!isOverWrite && this.ExtendedProperties.ContainsKey( item.Key ))
                    {
                        //如果不允许覆盖并且有同名属性，则忽略
                        continue;
                    }

                    //添加扩展属性
                    this.ExtendedProperties[item.Key] = this.GetExtendedPropertyValue( item.Value );
                }
            }
        }

        #endregion

        #region ---Private Method

        /// <summary>
        /// 初始化当前日志条目
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/9 9:34    创建
        /// </history>
        private void Intialize()
        {
            //获得扩展属性
            ICollection<KeyValuePair<string, object>> properties = LoggingContext.GetAllExtendedProperties();

            //添加全局扩展属性
            this.AppendExtendedProperties( properties, false );

            //判断应用程序域的名称是否已经初始化
            if (null == this.m_DomainName)
            {
                //获得应用程序域的名称
                this.m_DomainName = AppDomain.CurrentDomain.FriendlyName;
            }

            //判断用户名称是否已经初始化
            if (null == this.m_UserName)
            {
                //获得用户名称
                this.m_UserName = GetUsername();
            }

            //判断用户标识名称是否已经初始化
            if (null == this.m_Identity)
            {
                //获得用户标识
                this.m_Identity = GetIdentity();
            }

            //判断线程名称是否已经初始化
            if (null == this.m_ThreadName)
            {
                //记录线程名称
                this.m_ThreadName = Thread.CurrentThread.Name;

                //判断是否设置了线程名称
                if (string.IsNullOrEmpty( this.m_ThreadName ))
                {
                    //如果没有设置线程名称，则设置线程的ID
                    this.m_ThreadName = Thread.CurrentThread.ManagedThreadId.ToString( "G" );
                }
            }

            //判断调用堆栈信息是否初始化
            if (null == this.m_MethodName)
            {
                //初始化调用堆栈信息
                this.InitializeCallStackInformation();
            }
        }

        /// <summary>
        /// 获得扩展属性的值
        /// </summary>
        /// <param name="property">要获得扩展属性的值的扩展书信</param>
        /// <returns>扩展属性的值</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/21 12:03    创建
        /// </history>
        private object GetExtendedPropertyValue( object property )
        {
            //判断是否为NULL
            if (null == property)
            {
                //如果为NULL，则直接返回NULL
                return null;
            }

            //转化为扩展属性提供接口
            IExtendedPropertyProvider provider = property as IExtendedPropertyProvider;

            //判断是否实现了扩展属性提供接口
            if (null != provider)
            {
                //返回扩展属性
                return provider.GetExtendedProperty();
            }

            //返回属性值
            return property;
        }

        /// <summary>
        /// 获得应用系统的当前登录用户标识
        /// </summary>
        /// <returns>应用系统的当前登录用户标识</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 10:03    创建
        /// </history>
        private static string GetIdentity()
        {
            //用于保存主体名称
            string identity = DEFAULT_UNKNOWNNAME;

            //获得登陆用户名称
            try
            {
                //获得用户标识
                if (null != Thread.CurrentPrincipal &&
                    null != Thread.CurrentPrincipal.Identity &&
                    null != Thread.CurrentPrincipal.Identity.Name)
                {
                    //记录用户标识
                    identity = System.Threading.Thread.CurrentPrincipal.Identity.Name;
                }
            }
            catch (SecurityException ex)
            {
                //输出日志
                if (LoggingContext.MetaLog.IsErrorEnabled)
                {
                    LoggingContext.MetaLog.Error( ex, "获得当前系统用户的标识名称失败" );
                }
            }

            //返回用户标识
            return identity;
        }

        /// <summary>
        /// 获得操作系统的当前登录用户名称
        /// </summary>
        /// <returns>操作系统的当前登录用户名称</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/10/20 10:01    创建
        /// </history>
        private static string GetUsername()
        {
            //用于返回的用户名称
            string username = DEFAULT_UNKNOWNNAME;

            //获得登陆用户名称
            try
            {
                //获得当前登录的用户
                WindowsIdentity identity = WindowsIdentity.GetCurrent();

                //判断是否为NULL
                if (null != identity)
                {
                    username = identity.Name;
                }
            }
            catch (SecurityException ex)
            {
                //输出日志
                if (LoggingContext.MetaLog.IsErrorEnabled)
                {
                    LoggingContext.MetaLog.Error( ex, "获得当前已登录到Windows操作系统的人员的用户名失败" );
                }
            }

            //返回用户名称
            return username;
        }

        /// <summary>
        /// 初始化调用堆栈信息
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 11:03    创建
        /// </history>
        private void InitializeCallStackInformation()
        {
            //用于保存调用帧
            StackFrame frame = null;

            //判断是否有堆栈分界类型
            if (null != this.m_StackBoundaryType)
            {
                //获得调用帧
                frame = GetLatestCallStackFrame( this.m_StackBoundaryType );
            }

            //判断是否获得调用帧
            if (null != frame)
            {
                //获得调用方法信息
                System.Reflection.MethodBase method = frame.GetMethod();

                //判断是否有方法信息
                if (null != method)
                {
                    //设置方法名称
                    this.m_MethodName = method.Name;

                    //判断是否有声明类型
                    if (null != method.DeclaringType)
                    {
                        //设置类型名称
                        this.m_TypeName = method.DeclaringType.FullName;
                    }
                    else
                    {
                        //设置为默认值
                        this.m_TypeName = DEFAULT_UNKNOWNNAME;
                    }
                }
                else
                {
                    //设置为默认值
                    this.m_TypeName = DEFAULT_UNKNOWNNAME;
                    this.m_MethodName = DEFAULT_UNKNOWNNAME;
                }

                //获得文件名称
                this.m_FileName = frame.GetFileName();

                //获得行号
                this.m_LineNumber = frame.GetFileLineNumber();

                //获得列好
                this.m_ColumnNumber = frame.GetFileColumnNumber();
            }
            else
            {
                //设置为默认值
                this.m_TypeName = DEFAULT_UNKNOWNNAME;
                this.m_MethodName = DEFAULT_UNKNOWNNAME;
                this.m_FileName = DEFAULT_UNKNOWNNAME;
                this.m_LineNumber = -1;
                this.m_ColumnNumber = -1;
            }
        }

        /// <summary>
        /// 获得最后一帧调用堆栈帧
        /// </summary>
        /// <param name="stackBoundaryType">调用堆栈的分界类型</param>
        /// <returns>最后一帧调用堆栈帧</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/29 11:04    创建
        /// </history>
        private StackFrame GetLatestCallStackFrame( Type stackBoundaryType )
        {
            //创建调用堆栈跟踪
            StackTrace trace = new StackTrace( true );

            //判断是否有分界类型
            if (null == stackBoundaryType)
            {
                //如果没有，则返回第一帧
                if (trace.FrameCount > 0)
                {
                    return trace.GetFrame( 0 );
                }
                else
                {
                    return null;
                }
            }

            //用于保存调用帧序号
            int index = trace.FrameCount - 1;

            //用于保存调用帧
            StackFrame frame = null;

            //获得分界类型开始的第一个调用帧
            while (index >= 0)
            {
                //获得调用帧
                frame = trace.GetFrame( index );

                //判断是否为分界类型的调用帧
                if (null != frame && frame.GetMethod().ReflectedType == stackBoundaryType)
                {
                    //中断循环
                    break;
                }

                //减少序号
                index--;
            }

            //获得第一个不是分界类型的调用帧
            while (index < trace.FrameCount)
            {
                //获得调用帧
                frame = trace.GetFrame( index );

                //判断是否为分界类型的调用帧
                if (null != frame && frame.GetMethod().ReflectedType != stackBoundaryType)
                {
                    //返回调用帧
                    return frame;
                }

                //增加序号
                index++;
            }

            //默认返回NULL
            return null;
        }

        /// <summary>
        /// 获得当前进程的进程编号
        /// </summary>
        /// <returns>当前进程的进程编号</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/11/25 13:33    创建
        /// </history>
        private static int GetCurrentProcessID()
        {
            //获得当前进程
            using (Process currentProcess = Process.GetCurrentProcess())
            {
                //返回进程编号
                return currentProcess.Id;
            }
        }
        #endregion

        #region ---Field

        /// <summary>
        /// 日志事件发生的时间点
        /// </summary>
        private DateTime m_TimeStamp = DateTime.Now;

        /// <summary>
        /// 日志时间的级别
        /// </summary>
        private Level m_Level;

        /// <summary>
        /// 日志事件的描述信息
        /// </summary>
        private object m_Message;

        /// <summary>
        /// 记录当前日志消息的日志记录器的名称
        /// </summary>
        private string m_LoggerName;

        /// <summary>
        /// 日志事件中包含的异常
        /// </summary>
        private Exception m_Exception;

        /// <summary>
        /// 当前已登录到Windows操作系统的人员的用户名
        /// </summary>
        private string m_UserName;

        /// <summary>
        /// 当前系统用户的标识名称
        /// </summary>
        private string m_Identity;

        /// <summary>
        /// 当前进程的进程编号
        /// </summary>
        private static int s_ProcessID;

        /// <summary>
        /// 日志事件发生点所在线程的名称
        /// </summary>
        private string m_ThreadName;

        /// <summary>
        /// 应用程序域的名称
        /// </summary>
        private string m_DomainName;

        /// <summary>
        /// 日志事件发生点所在类型的名称
        /// </summary>
        private string m_TypeName;

        /// <summary>
        /// 日志事件发生点所在方法的名称
        /// </summary>
        private string m_MethodName;

        /// <summary>
        /// 日志事件发生点所在文件的名称
        /// </summary>
        private string m_FileName;

        /// <summary>
        /// 日志事件发生点所在文件的行号
        /// </summary>
        private int m_LineNumber;

        /// <summary>
        /// 日志事件发生点所在文件的列号
        /// </summary>
        private int m_ColumnNumber;

        /// <summary>
        /// 堆栈分界类型
        /// </summary>
        [NonSerialized]
        private Type m_StackBoundaryType;

        /// <summary>
        /// 扩展属性
        /// </summary>
        private IDictionary<string, object> m_ExtendedProperties;

        #endregion

        #region ---Const

        /// <summary>
        /// 默认位置名称
        /// </summary>
        private const string DEFAULT_UNKNOWNNAME = "?";

        #endregion
    }
}
